package com.example.gcmtest;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.FragmentManager;
import android.util.Log;

import com.example.gcmtest.MarathonDataBase.Convention;
import com.example.gcmtest.MarathonDataBase.MarathonDataBase;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.GroundOverlay;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.maps.GeoPoint;

public class MapActivity extends android.support.v4.app.FragmentActivity implements LocationListener, OnCameraChangeListener {

	// <<< yamagata wrote
    static final float INITIAL_ZOOM_LEVEL = 16;
    static final double INITIAL_LATITUDE = 34.692068;
    static final double INITIAL_LONGITUDE = 135.530063;
    // >>> yamagata worte

    private MarathonDataBase marathonDB;

	// メンバー変数
	private double latitude;
	private double longitude;

	//IDBG 0621 ズーム率取得とのためメンバー変数に変更
	private CameraPosition pos;

	Looper looper;
	Handler mhandler;
	GroundOverlayOptions[] options_overlay = new GroundOverlayOptions[CommonUtilities.MAX_REGISTER];
	int changeNo;

	// コース区間番号記憶用
	private int section = 0;

	//private double test_num1;
	//private double test_num2;

	//GeoPoint格納用
	GeoPoint gp_S;
	GeoPoint gp_E;
	GeoPoint gp_P;

	//IDBG 0621 拡縮変更処理
	float now_zoom=0.0f;
	// GoogleMap
	private GoogleMap map;
	private LocationManager locationManager;
	private MarkerOptions options_m = new MarkerOptions();
	//
	GroundOverlay[] overlay = new GroundOverlay[CommonUtilities.MAX_REGISTER];

	//java.util.Arrays#fill(array, object)
	private boolean[] ol_flg = {false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false};

	//コンストラクタ
	public MapActivity()
	{
		marathonDB = MarathonDataBase.getInstance();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_map);

		// Fragmentの取得
		FragmentManager manager = getSupportFragmentManager();
		SupportMapFragment frag = (SupportMapFragment) manager.findFragmentById(R.id.map);

		// GoogleMapの取得
		map = frag.getMap();

		// LocationManagerインスタンスの取得
		locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);

		// 位置情報の更新を受け取るように設定
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
//		locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);

		// XMLからマーカー値を取得
		/*
		Resources res = getResources();
		test_num1 = Double.parseDouble (res.getString (R.string.test_num1));
		test_num2 = Double.parseDouble (res.getString (R.string.test_num2));
		MarkerOptions options_m = new MarkerOptions();
		options_m.position(new LatLng(test_num1,test_num2));
		options_m.title("50m地点");
		map.addMarker(options_m);
		*/

		// <<< yamagata wrote
        //初期位置
		//規定値にセットする
        LatLng target = new LatLng(INITIAL_LATITUDE,INITIAL_LONGITUDE);
        //ズームレベル
        float zoom = INITIAL_ZOOM_LEVEL;
        //チルトアングル
        float tilt = 0.0f; // 0.0 - 90.0
        //向き
        float bearing = 0.0f;
        //CameraUpdate
        CameraPosition pos = new CameraPosition(target, zoom, tilt, bearing);
        CameraUpdate camera = CameraUpdateFactory.newCameraPosition(pos);
        // カメラ位置移動
        map.moveCamera(camera);
        // >>> yamagata worte

		// ArrayListにデータを入れる
     // <<< 2013.06.13 wrote by yamagata

        // 大会コースデータリストを取得
        ArrayList<Convention> conventionList = marathonDB.GetConventionList();

        // 大会コースを設定
        // ダミーデータ、今回は先頭(大阪マラソン)を設定する。
        Boolean ret = marathonDB.SetConvention(conventionList.get(0).No);
        Log.v("MarathonApplication", "[" + ret + "]ConventionNo :" + conventionList.get(0).No);
        if(ret == true)
        {
    		// 現在位置&コース描画
    		// ライン
    		PolylineOptions options = new PolylineOptions();
    		options.color(Color.RED);
    		options.width(10);
    		options.geodesic(true); // 測地線で表示

    		double line_latitude; // 緯度
    		double line_longitude; // 経度

    		for(int i = 0; i <marathonDB.GetCourseMaxPointNum(); i++)
        	{
    			line_latitude  = marathonDB.GetCourseDataLatitude(i);
    			line_longitude = marathonDB.GetCourseDataLangitude(i);
    	        Log.v("MarathonApplication", "line_latitude[" + line_latitude + "]line_longitude[" + line_longitude + "]");
    			if((line_latitude == 0) && (line_longitude == 0))
    			{
    				break;
    			}
        		options.add(new LatLng(line_latitude, line_longitude));
        	}
    		//IDBG 0621 階層順設定
    		options.zIndex(0);
    		map.addPolyline(options);
        }
		// >>> 2013.06.13 wrote by yamagata

     // 受信スレッド
	new Thread(new Runnable() {
        @Override
        public void run() {
        	boolean end_flg=false;
        	while(end_flg==false){
				boolean gps_flg = marathonDB.getBoolean("GPS_FLG",false);
				changeNo = marathonDB.getInteger("CHANGE_NO",0);
				String lati  = marathonDB.getText("RUN_LATI"+changeNo, "0.0");
				String longi = marathonDB.getText("RUN_LONGI"+changeNo, "0.0");


				// GPS情報が更新された時の処理
				if(gps_flg==true){
					double run_lati = Double.parseDouble(lati);
					double run_longi = Double.parseDouble(longi);

					/*******************************************************************/
			        // コーナーから10m以内なら、次の区間の開始地点から表示する
			        CalcDistance CalcDis = new CalcDistance();
			        /* 値を取得して表示します。 */
			        double DistancePtoE = CalcDis.distance_atob(run_lati, run_longi, marathonDB.GetCourseDataLatitude(section + 1), marathonDB.GetCourseDataLangitude(section + 1), 'K');
					if(10 >= DistancePtoE){
						section++;
					}
					/*******************************************************************/

					LatLng position = new LatLng(run_lati, run_longi);
					BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.ic_logo);
					GroundOverlayOptions options_ol = new GroundOverlayOptions();
					options_overlay[changeNo] = options_ol;



					// 貼り付ける設定
			    	options_overlay[changeNo].image(descriptor);
			    	//IDBG 0621 アンカー値変更
			    	options_overlay[changeNo].anchor(0.55f,0.5f);
			    	//IDBG 0621 階層順設定
			    	options_overlay[changeNo].zIndex(1);

			    	//IDBG 0621 ズーム率取得
			    	looper = Looper.getMainLooper();
		        	mhandler = new Handler(looper);
		        	mhandler.post(new Runnable() {
		        		@Override
		        		public void run() {
		        			now_zoom = map.getCameraPosition().zoom;
		        			//Log.v("activate","zoom:" + zoom);
		        		}
		        	});


					//IDBG 0621 拡縮調整
					if(now_zoom >= 18){
						options_overlay[changeNo].position(position, 10f);
					}
					else if(now_zoom <= 6){
						options_overlay[changeNo].position(position, 160f);
					}
					else{
						options_overlay[changeNo].position(position, 40f);
					}

					if(ol_flg[changeNo] == false){
						looper = Looper.getMainLooper();
			        	mhandler = new Handler(looper);
			        	mhandler.post(new Runnable() {
			        		@Override
			        		public void run() {
			        			// UI部品への操作
			        			overlay[changeNo] = map.addGroundOverlay(options_overlay[changeNo]);
			        			overlay[changeNo].setBearing(marathonDB.GetCourseDataAngle(section));

			        		}
			        	});

					}
					// マップに貼り付け・アルファを設定
					if(ol_flg[changeNo] == true){
						looper = Looper.getMainLooper();
			        	mhandler = new Handler(looper);
			        	mhandler.post(new Runnable() {
			        		@Override
			        		public void run() {
								overlay[changeNo].remove();
								overlay[changeNo] = map.addGroundOverlay(options_overlay[changeNo]);
								overlay[changeNo].setBearing(marathonDB.GetCourseDataAngle(section));

			        		}
			        	});
					}
					ol_flg[changeNo] = true;
					marathonDB.setBoolean("GPS_FLG",false );
				}

				// ディレイ処理
				try {
        			// 無限ループを0.5秒止める(これがないと延々この処理だけが動いてしまい、送信処理をうけつけなくなる、むしろ落ちる)
					Thread.sleep(500);
				} catch(InterruptedException except) {
					except.printStackTrace();
				}
        	}
        }
     }).start();


	}

	// 位置情報が更新されると、onLocationChanged()が呼び出される。
	// 引数として渡されたLocationを参照することで位置情報の詳細を取得できます。
	@Override
	public void onLocationChanged(Location myLocate) {
		// TODO 自動生成されたメソッド・スタブ

		// 緯度経度の取得
		if(null != myLocate){
			// 緯度の取得
			latitude = (double) (myLocate.getLatitude());
			// 経度の取得
			longitude = (double) (myLocate.getLongitude());

			// 現在位置更新
			/* 自機位置更新版*/
			MyLocationSource source = new MyLocationSource();
			map.setLocationSource(source);
			map.setMyLocationEnabled(true);
		}
	}

	//現在位置を好きな緯度・経度に設定する
	private class MyLocationSource implements LocationSource {
	    @Override
	    public void activate(OnLocationChangedListener listener) {
	        // 好きな緯度・経度を設定した Location を作成
	        Location location = new Location("MyLocation");

			// 現在位置描画
			location.setLatitude(latitude);
			location.setLongitude(longitude);
			location.setAccuracy(100); // 精度
			// Location に設定
	        listener.onLocationChanged(location);
	    }

	    // 処理を止めるときに使う
	    @Override
	    public void deactivate() {
	    }

	}

	@Override
	public void onProviderDisabled(String arg0) {
		// TODO 自動生成されたメソッド・スタブ

	}
	@Override
	public void onProviderEnabled(String arg0) {
		// TODO 自動生成されたメソッド・スタブ

	}
	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO 自動生成されたメソッド・スタブ

	}
	//IDBG 0621 拡縮変化時処理
	@Override
	public void onCameraChange(CameraPosition pos){
		float zoom = 0;

		zoom = map.getCameraPosition().zoom;
		Log.v("activate","zoom:" + zoom);

	}
}
